package winFrom

import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-adodb"
	"time"
	//"html/template"
	"io"
	//"log"
	"net/http"
	"os"
	"strconv"
	"strings"
)

type sqlhelp struct {
	sqlinfo
	Tb_urls []Tb_url
}
type sqlhelp_See struct {
	sqlinfo
	Tb_urls []*Tb_url
}
type sqlinfo struct {
	datafile       string
	datadriver     string
	dataSourceName string
	db             *sql.DB
}
type Tb_url struct {
	urlid        int32
	softWareName string
	osInfo       string
	url          string
	isDownload   int //0未初始化，1开始执行，2执行完成
	startTime    string
	endTime      string
}

var chn chan Tb_url
var chn_en chan Tb_url

const maxchn = 20

func (tb *Tb_url) loadinstall(tb1 Tb_url) {
	if tb1.isDownload == 1 {

		tm, err := time.Parse("2006/1/2 15:04:05", tb.startTime)
		if err != nil {
			fmt.Println("时间转换失败")
			fmt.Println(tb1.urlid)
		}
		if time.Now().Day() > tm.Day() {
			tb.ExecUrlListSql(`update Tb_url set isDownload='-1' where  url= '` + tb1.url + `'`)
		}

	}
	if tb1.isDownload == 0 {
		tb1.isDownload = 1

		tb1.ExecUrlListSql("update tb_url set startTime='" + time.Now().Format("2006/1/2 15:04:05") + "'" + `
		, isDownload='` + fmt.Sprintf("%d", 1) + `' where  urlid =` + fmt.Sprintf("%d", tb1.urlid) + ``)

		tb1.HttpDownload(tb1.url)

		chn <- tb1
		return
	}
	chn_en <- tb1

}
func (tb *Tb_url) UpdateData(bj int32) {
	var sql_up sqlinfo
	sql_up.init()
	sql_up.db, _ = sql.Open(sql_up.datadriver, sql_up.dataSourceName)
	defer sql_up.db.Close()

	_, err := sql_up.db.Exec(`update  Tb_url set isDownload='` + fmt.Sprintf("%d", bj) + `' where  urlid =` + fmt.Sprintf("%d", tb.urlid) + ``)
	if err != nil {
		fmt.Println("update Error", err)
		return
	}

}
func (tb *sqlhelp) ExecUrlListSql(sql_str string) {
	var sql_up sqlinfo
	sql_up.init()
	sql_up.db, _ = sql.Open(sql_up.datadriver, sql_up.dataSourceName)
	defer sql_up.db.Close()

	_, err := sql_up.db.Exec(sql_str)
	if err != nil {
		fmt.Println("ExecUrlListSql 失败", err)
		return
	}

}
func (tb *Tb_url) ExecUrlListSql(sql_str string) {
	var sql_up sqlinfo
	sql_up.init()
	sql_up.db, _ = sql.Open(sql_up.datadriver, sql_up.dataSourceName)
	defer sql_up.db.Close()

	_, err := sql_up.db.Exec(sql_str)
	if err != nil {
		fmt.Println("ExecUrlListSql 失败", err)
		return
	}

}
func (tb *Tb_url) IfExsitesRow(sql_str string) (r int) {
	var sql_up sqlinfo
	sql_up.init()
	sql_up.db, _ = sql.Open(sql_up.datadriver, sql_up.dataSourceName)
	defer sql_up.db.Close()

	stmt, err := sql_up.db.Prepare(sql_str)
	if err != nil {
		fmt.Println("Query Error", err)
		return
	}
	rows, err := stmt.Query()
	if err != nil {
		fmt.Println("stmt Error", err)
		return
	}
	defer rows.Close()

	for rows.Next() {

		return 1
	}
	return 0
	//_, err := sql_up.db.Exec(sql_str)
	//if err != nil {
	//	fmt.Println("ExecUrlListSql 失败", err)
	//	return
	//}

}
func (tb *Tb_url) HttpDownload(httpUrl string) {

	url := strings.Replace(httpUrl, "http://", "", -1)

	strSqlit := strings.Split(url, "/")
	UrlString := "./download/" + strings.Replace(url, strSqlit[strings.Count(url, "/")], "", -1)
	fmt.Printf(UrlString)

	os.MkdirAll(UrlString, 0777)
	if strSqlit[strings.Count(url, "/")] == "" {
		strSqlit[strings.Count(url, "/")] = "新文件.html"
	}
	f, err := os.OpenFile(UrlString+strSqlit[strings.Count(url, "/")], os.O_APPEND|os.O_RDWR|os.O_CREATE, 0777) //其实这里的 O_RDWR应该是 O_RDWR|O_CREATE，也就是文件不存在的情况下就建一个空文件，但是因为windows下还有BUG，如果使用这个O_CREATE，就会直接清空文件，所以这里就不用了这个标志，你自己事先建立好文件。

	if err != nil {
		fmt.Printf("创建文件错误文件为%s", UrlString)
	}
	resp, err := http.DefaultClient.Get(httpUrl)
	written, err := io.Copy(f, resp.Body)
	if err != nil {
		fmt.Printf("############:http下载链接错误")
	}
	fmt.Printf("############:http下载个数:%d ", written)
}
func (shelp *sqlhelp) Reflash_tbs(slice *[]Tb_url, start int) {
	/*递归删除*/
	end := start
	if start >= len(*slice) {
		return
	}
	if (*slice)[start].isDownload == 2 {
		end++
		fmt.Printf("slice 删除开始 编号为:%d", (*slice)[start].urlid) //test
		fmt.Println("")
		result := make([]Tb_url, len(*slice)-(end-start))
		at := copy(result, (*slice)[:start])
		copy(result[at:], (*slice)[end:])
		*slice = result
		start = at - 1

	}
	start++
	shelp.Reflash_tbs(slice, start)

}

func (shelp *sqlhelp) Remove(slice []Tb_url, start, end int) []Tb_url {
	result := make([]Tb_url, len(slice)-(end-start))
	at := copy(result, slice[:start])
	copy(result[at:], slice[end:])

	return result
}

func (shelp *sqlinfo) init() {
	shelp.datadriver = "adodb"
	shelp.datafile = "./downloadfile.mdb"
	if _, err := os.Stat("./downloadfile.mdb"); err != nil {
		fmt.Println("打开数据库失败 'example.mdb'.")
		return

	}
	shelp.dataSourceName = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=./downloadfile.mdb;Persist Security Info=True;Jet OLEDB:Database Password=123456"
	if _, err := os.Stat(shelp.datafile); err != nil {
		fmt.Println("put here empty database named ''.")
		return
	}

}

func (shelp *sqlhelp) startDownload() {

	var i Tb_url

	chn = make(chan Tb_url)
	chn_en = make(chan Tb_url)
	for _, tb := range shelp.Tb_urls {
		fmt.Println(tb.urlid + 500)
		fmt.Println(tb.url)
		go tb.loadinstall(tb)

	}

	for _, _ = range shelp.Tb_urls {
		j := 0
		j++
		select {
		case i = <-chn:
			if i.isDownload == 1 {

				i.ExecUrlListSql("update tb_url set endTime='" + time.Now().Format("2006/1/2 15:04:05") + "'" + `
		, isDownload='` + fmt.Sprintf("%d", 2) + `' where  urlid =` + fmt.Sprintf("%d", i.urlid) + ``)
				for v, tb := range shelp.Tb_urls {
					if tb.urlid == i.urlid {
						shelp.Tb_urls[v].isDownload = 2
					}
				}
				i.isDownload = 2
				fmt.Println("完成下载修改下载状态")
			}
		case i = <-chn_en:
			continue
		}

	}
	shelp.Reflash_tbs(&shelp.Tb_urls, 0)

	for _, tb := range shelp.Tb_urls {
		fmt.Printf("删除后存在节点%d，下载队列为%d", tb.isDownload, len(shelp.Tb_urls)) //test
	}

}
func (shelp *sqlhelp) Ini_Tb_url_urls(str string, urls *[]Tb_url) {

	shelp.init()
	var err error
	shelp.db, err = sql.Open(shelp.datadriver, shelp.dataSourceName)
	defer shelp.db.Close()
	if err != nil {
		fmt.Println("打开数据库失败")
		return
	}

	stmt, err := shelp.db.Prepare(str)
	if err != nil {
		fmt.Println("创建数据库队列失败", err)
		return
	}
	defer stmt.Close()
	rows, err := stmt.Query()
	if err != nil {
		fmt.Println(" Ini_Tb_url_urls 创建数据库队列失败")
		return
	}
	defer rows.Close()

	for rows.Next() {

		var tburl Tb_url
		var isDownloads string

		rows.Scan(&tburl.urlid, &tburl.url, &isDownloads, &tburl.startTime, &tburl.endTime)
		aa, _ := strconv.Atoi(isDownloads)
		tburl.isDownload = aa
		*urls = append(*urls, tburl)

	}

}
func (shelp *sqlhelp) Ini_Tb_url(str string) {
	shelp.init()
	var err error
	shelp.db, err = sql.Open(shelp.datadriver, shelp.dataSourceName)
	defer shelp.db.Close()
	if err != nil {
		fmt.Println("aaa")
		return
	}

	stmt, err := shelp.db.Prepare(str)
	if err != nil {
		fmt.Println("Query Error", err)
		return
	}
	defer stmt.Close()
	rows, err := stmt.Query()
	if err != nil {
		fmt.Println(" Ini_Tb_url row is bad")
		return
	}
	defer rows.Close()
	fmt.Println(" start Ini_Tb_url Row  ")
	for rows.Next() {

		var tburl Tb_url

		rows.Scan(&tburl.urlid, &tburl.url, &tburl.isDownload, &tburl.startTime, &tburl.endTime)
		if tburl.urlid != 0 {
			fmt.Println("tburl.urlid ", tburl.urlid)
			shelp.Tb_urls = append(shelp.Tb_urls, tburl)
		}

	}

}

func (shelp *sqlhelp) Ini_Tb_url_Clear(str string) {
	shelp.init()
	var err error
	shelp.db, err = sql.Open(shelp.datadriver, shelp.dataSourceName)
	defer shelp.db.Close()
	if err != nil {
		fmt.Println("aaa")
		return
	}
	stmt, err := shelp.db.Prepare(str)
	if err != nil {
		fmt.Println("Query Error", err)
		return
	}
	rows, err := stmt.Query()
	if err != nil {
		fmt.Println(" Ini_Tb_url_Clear row is bad")
		return
	}
	defer rows.Close()
	shelp.Tb_urls = nil
	for rows.Next() {

		var tburl Tb_url

		rows.Scan(&tburl.urlid, &tburl.url, &tburl.isDownload, &tburl.startTime, &tburl.endTime)
		shelp.Tb_urls = append(shelp.Tb_urls, tburl)

	}

}
func (shelp *sqlhelp) RetUrlDownlodingCount() int {
	shelp.init()
	var err error
	shelp.db, err = sql.Open(shelp.datadriver, shelp.dataSourceName)
	defer shelp.db.Close()
	if err != nil {
		fmt.Println("aaa")
		return 3
	}
	stmt, err := shelp.db.Prepare("select top 1 url_count from UrlCount")
	if err != nil {
		fmt.Println("RetUrlDownlodingCountQuery Error", err)
		return 3
	}
	rows, err := stmt.Query()
	if err != nil {
		fmt.Println(" RetUrlDownlodingCount row is bad")
		return 3
	}
	defer rows.Close()

	for rows.Next() {

		var url_count int

		rows.Scan(&url_count)
		return url_count

	}
	return 3

}
func (shelp *sqlhelp) RetUrlIsDownloding() bool {
	shelp.init()
	var err error
	shelp.db, err = sql.Open(shelp.datadriver, shelp.dataSourceName)
	defer shelp.db.Close()
	if err != nil {
		fmt.Println("aaa")
		return false
	}
	stmt, err := shelp.db.Prepare("select top 1 buttonint from UrlCount")
	if err != nil {
		fmt.Println("RetUrlDownlodingCountQuery Error", err)
		return false
	}
	rows, err := stmt.Query()
	if err != nil {
		fmt.Println(" RetUrlDownlodingCount row is bad")
		return false
	}
	defer rows.Close()

	for rows.Next() {

		var url_count int

		rows.Scan(&url_count)
		if url_count == 0 {
			return false
		} else {
			return true
		}
		return false

	}
	return false

}
